package en.edu.zxj.mq.mqserver.datacenter;

import en.edu.zxj.mq.common.MqException;
import en.edu.zxj.mq.common.util.BinaryUtils;
import en.edu.zxj.mq.mqserver.core.Binding;
import en.edu.zxj.mq.mqserver.core.Exchange;
import en.edu.zxj.mq.mqserver.core.MSGQueue;
import en.edu.zxj.mq.mqserver.core.Message;
import org.jetbrains.annotations.NotNull;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description：封装访问磁盘数据操作: 数据库 + 文件
 * 1. 数据库: 交换机, 消息队列, 绑定
 * 2. 文件: 消息
 * 上层逻辑如果需要访问磁盘, 就直接调用这个类, 不需要知道下层访问的是数据库还是文件
 *
 * @author: zxj
 * @date: 2024-02-28
 * @time: 21:28:00
 */
public class DiskDataCenter {
    private DatabaseManager databaseManager = new DatabaseManager();
    private MessageFileManger messageFileManger = new MessageFileManger();


    public void init() {
        databaseManager.init();
        messageFileManger.init();
    }

    /*
     * 封装交换机操作
     */
    public Integer insertExchange(Exchange exchange) {
        return databaseManager.insertExchange(exchange);
    }

    public Integer deleteExchangeByName(String name) {
        return databaseManager.deleteExchangeByName(name);
    }

    public List<Exchange> selectAllExchanges() {
        return databaseManager.selectAllExchanges();
    }

    /*
     * 封装消息队列操作
     */
    public Integer insertMSGQueue(MSGQueue msgQueue) throws IOException {
        Integer ret = databaseManager.insertMSGQueue(msgQueue);
        messageFileManger.createQueueFiles(msgQueue.getName());
        return ret;
    }

    public Integer deleteMSGQueueByName(String name) throws IOException {
        Integer ret = databaseManager.deleteMSGQueueByName(name);
        messageFileManger.destroyQueueFiles(name);
        return ret;
    }

    public List<MSGQueue> selectAllMSGQueues() {
        return databaseManager.selectAllMSGQueues();
    }


    /*
     * 封装绑定机操作
     */
    public Integer insertBinding(Binding binding) {
        return databaseManager.insertBinding(binding);
    }

    public Integer deleteBinding(String exchangeName, String queueName) {
        return databaseManager.deleteBinding(exchangeName, queueName);
    }

    public List<Binding> selectAllBindings() {
        return databaseManager.selectAllBindings();
    }

    /*
     *   封装消息操作
     */
    public void createQueueFiles(String queueName) throws IOException {
        messageFileManger.createQueueFiles(queueName);
    }

    public void destroyQueueFiles(String queueName) throws IOException {
        messageFileManger.destroyQueueFiles(queueName);
    }


    public boolean checkFilesExists(String queueName) {
        return messageFileManger.checkFilesExists(queueName);
    }


    public void sendMessage(@NotNull MSGQueue msgQueue, Message message) throws MqException, IOException {
        messageFileManger.sendMessage(msgQueue, message);
    }


    public void deleteMessage(@NotNull MSGQueue msgQueue, @NotNull Message message) throws IOException, ClassNotFoundException, MqException {
        messageFileManger.deleteMessage(msgQueue, message);
        // 删除一条信息之后, 判断是否需要 gc
        if (messageFileManger.checkGC(msgQueue.getName())) {
            messageFileManger.gc(msgQueue);
        }
    }

    public LinkedList<Message> loadAllMessageFromQueue(String queueName) throws IOException, MqException, ClassNotFoundException {
        return messageFileManger.loadAllMessageFromQueue(queueName);
    }
}
